﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using M3G;

namespace MyTestProject {
    public class TestSetUniformValue {
        [Fact]
        public void TestSetUniformValueBool () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Robina Gibbes", ShaderVariableType.Bool, 0);

            unifs.SetUniformValue (id, true);

            var value = (bool)unifs.GetUniformValue (id);
            Assert.Equal (true, value);
        }

        [Fact]
        public void TestSetUniformValueBool2 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Carla G. E. von Rosen", ShaderVariableType.BVec2, 0);

            unifs.SetUniformValue (id, true, false);

            var values = (bool[])unifs.GetUniformValue (id);

            Assert.Equal (true, values[0]);
            Assert.Equal (false, values[1]);
        }

        [Fact]
        public void TestSetUniformValueBool3 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Isabelle du Monceau de Bergendal", ShaderVariableType.BVec3, 0);

            unifs.SetUniformValue (id, true, false, true);

            var values = (bool[])unifs.GetUniformValue (id);

            Assert.Equal (true, values[0]);
            Assert.Equal (false, values[1]);
            Assert.Equal (true, values[2]);
        }

        [Fact]
        public void TestSetUniformValueBool4 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Rosalie de Hemricourt de Grunne", ShaderVariableType.BVec4, 0);

            unifs.SetUniformValue (id, true, false, true, false);

            var values = (bool[])unifs.GetUniformValue (id);

            Assert.Equal (true, values[0]);
            Assert.Equal (false, values[1]);
            Assert.Equal (true, values[2]);
            Assert.Equal (false, values[3]);
        }

        [Fact]
        public void TestSetUniformValueFloat () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Dolores Bader", ShaderVariableType.Float, 0);

            unifs.SetUniformValue (id, 1.0f);

            var value = (float)unifs.GetUniformValue (id);

            Assert.Equal (1.0f, value);
        }

        [Fact]
        public void TestSetUniformValueVec2 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Elizabeth F. Beurling", ShaderVariableType.Vec2, 0);

            unifs.SetUniformValue (id, 1.0f, 2.0f);

            var values = (float[])unifs.GetUniformValue (id);

            Assert.Equal (1.0f, values[0]);
            Assert.Equal (2.0f, values[1]);
        }


        [Fact]
        public void TestSetUniformValueVec3 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Lynette Bishop", ShaderVariableType.Vec3, 0);

            unifs.SetUniformValue (id, 1.0f, 2.0f, 3.0f);

            var values = (float[])unifs.GetUniformValue (id);

            Assert.Equal (1.0f, values[0]);
            Assert.Equal (2.0f, values[1]);
            Assert.Equal (3.0f, values[2]);
        }

        [Fact]
        public void TestSetUniformValueVec4 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Minnie Bishop ", ShaderVariableType.Vec4, 0);

            unifs.SetUniformValue (id, 1.0f, 2.0f, 3.0f, 4.0f);

            var values = (float[])unifs.GetUniformValue (id);

            Assert.Equal (1.0f, values[0]);
            Assert.Equal (2.0f, values[1]);
            Assert.Equal (3.0f, values[2]);
            Assert.Equal (4.0f, values[3]);
        }

        [Fact]
        public void TestSetUniformValueInt () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Wilma Bishop", ShaderVariableType.Int, 0);

            unifs.SetUniformValue (id, 1);

            var value = (int)unifs.GetUniformValue (id);

            Assert.Equal (1, value);
        }

        [Fact]
        public void TestSetUniformValueInt2 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Delia Jeram", ShaderVariableType.IVec2, 0);

            unifs.SetUniformValue (id, 1, 2);

            var values = (int[])unifs.GetUniformValue (id);

            Assert.Equal (1, values[0]);
            Assert.Equal (2, values[1]);
        }

        [Fact]
        public void TestSetUniformValueInt3 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Adolpha Malan", ShaderVariableType.IVec3, 0);

            unifs.SetUniformValue (id, 1, 2, 3);

            var values = (int[])unifs.GetUniformValue (id);

            Assert.Equal (1, values[0]);
            Assert.Equal (2, values[1]);
            Assert.Equal (3, values[2]);
        }

        [Fact]
        public void TestSetUniformValueInt4 () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Cecilia Glinda Miles", ShaderVariableType.IVec4, 0);

            unifs.SetUniformValue (id, 1, 2, 3, 4);

            var values = (int[])unifs.GetUniformValue(id);

            Assert.Equal (1, values[0]);
            Assert.Equal (2, values[1]);
            Assert.Equal (3, values[2]);
            Assert.Equal (4, values[3]);
        }

        [Fact]
        public void TestSetUniformValueSampler () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Patricia Schade", ShaderVariableType.Sampler2D, 0);
            var img   = new Image2D (Image2D.RGB, 32, 32);
            var tex   = new Texture2D (img);

            unifs.SetUniformValue (id, tex);

            var value = (Texture2D)unifs.GetUniformValue(id);

            Assert.Equal (tex, value);
        }

        /**
         * TransformはStruct型なので値が等しいと言うこと
         * */
        [Fact]
        public void TestSetUniformValueTransform () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Constantia Cantacuzino", ShaderVariableType.Mat4, 0);
            var cam   = new Camera();
            cam.SetPerspective (45.0f, 1.33f, 0.1f, 100f);
            var tra   = cam.ProjectionTransform;

            unifs.SetUniformValue (id, tra);

            var value = (Transform)unifs.GetUniformValue (id);

            Assert.Equal (tra, value);
        }

        [Fact]
        public void TestSetUniformValueArrayBool () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Anabuki Tomoko", ShaderVariableType.BVec2, 2);

            unifs.SetUniformValueArray (id, new bool[]{true, false, true, false});

            var values = (bool[])unifs.GetUniformValue (id);

            Assert.Equal (true , values[0]);
            Assert.Equal (false, values[1]);
            Assert.Equal (true , values[2]);
            Assert.Equal (false, values[3]);
        }

        [Fact]
        public void TestSetUniformValueArrayFloat () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Etou Toshiko", ShaderVariableType.Vec2, 2);

            unifs.SetUniformValueArray (id, new float[] {1.0f, 2.0f, 3.0f, 4.0f});

            var values = (float[])unifs.GetUniformValue (id);

            Assert.Equal (1.0f, values[0]);
            Assert.Equal (2.0f, values[1]);
            Assert.Equal (3.0f, values[2]);
            Assert.Equal (4.0f, values[3]);
        }

        [Fact]
        public void TestSetUniformValueArrayInt () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Hattori Shizuka", ShaderVariableType.IVec2, 2);

            unifs.SetUniformValueArray (id, new int[] { 1, 2, 3, 4});

            var values = (int[])unifs.GetUniformValue (id);

            Assert.Equal (1, values[0]);
            Assert.Equal (2, values[1]);
            Assert.Equal (3, values[2]);
            Assert.Equal (4, values[3]);
        }

        [Fact]
        public void TestSetUniformValueArraySampler () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Inagaki Mami", ShaderVariableType.Sampler2D, 2);
            var img   = new Image2D (Image2D.RGB, 32, 32);
            var tex1  = new Texture2D (img);
            var tex2  = new Texture2D (img);

            unifs.SetUniformValue (id, new Texture2D[] { tex1, tex2 });

            var values = (Texture2D[])unifs.GetUniformValue (id);

            Assert.Equal (tex1, values[0]);
            Assert.Equal (tex2, values[1]);
        }

        /**
         * TransformはStruct型なので値が等しいと言うこと
         * */
        [Fact]
        public void TestSetUniformValueArrayTransform () {
            var unifs = new ShaderUniforms ();
            var id    = unifs.AddUniform ("Inufusa Yuno", ShaderVariableType.Mat4, 2);
            var cam1   = new Camera ();
            var cam2   = new Camera ();
            cam1.SetPerspective (45.0f, 1.33f, 0.1f, 100f);
            cam2.SetPerspective (60.0f, 1.33f, 10f, 10000f);
            var tra1   = cam1.ProjectionTransform;
            var tra2   = cam1.ProjectionTransform;

            unifs.SetUniformValueArray (id, new Transform[]{tra1, tra2});

            var values = (Transform[])unifs.GetUniformValue (id);

            Assert.Equal (tra1, values[0]);
            Assert.Equal (tra2, values[1]);
        }
    }
}
